module dactor.dist;

private import dactor.coroutine;
private import dactor.util;

class NodeManager
{
    private Pid[uint] proxies;
    private Pid[string] nameMap;

    private uint counter = 0;

    public uint registerNode(string name, Pid proxyPid) {
        if (name in nameMap) {
            return 0;
        }
        nameMap[name] = proxyPid;
        while (true) {
            uint node = ++ counter;
            if (node == 0 || (node in proxies)) {
                continue;
            }
            proxies[node] = proxyPid;
            return node;
        }
    }

    public void unregisterNode(uint node, string name, Pid proxyPid) {
        if (Pid* pid = (node in proxies)) {
            if (*pid == proxyPid) {
                proxies.remove(node);

                if (pid == (name in nameMap)) {
                    if (*pid == proxyPid) {
                        nameMap.remove(name);
                    }
                }
            }
        }
    }

    public Pid findProxy(string name) const {
        if (const(Pid)* pid = (name in nameMap)) {
            return *pid;
        }
        return Pid.INVALID_PID;
    }

    public Pid findProxy(uint node) const {
        if (const(Pid)* pid = (node in proxies)) {
            return *pid;
        }
        return Pid.INVALID_PID;
    }

    private static NodeManager _instance = null;

    public static NodeManager instance() {
        if (!_instance) {
            _instance = new NodeManager;
        }
        return _instance;
    }
}

